const is = (tokens) => {
  return tokens.peek().type === 'keyword' && tokens.peek().value === 'fun'
}

const parse = (tokens) => {
  const node = {
    type: 'FunctionDeclaration',
    id: {
      type: 'Identifier',
      name: ''
    },
    params: [],
    body: {
      type: 'NativeFunctionBody',
      body: []
    }
  }

  tokens.next()

  if (tokens.peek().type !== 'identifier') {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  node.id.name = tokens.peek().value

  tokens.next()

  if (tokens.peek().type === 'operator' && tokens.peek().value === ':=') {
    tokens.next()

    if (tokens.peek().type === 'keyword' && tokens.peek().value === 'native') {
      node.body.type = 'NativeFunctionBody'
      node.body.body = node.id.name
      tokens.next()
    } else if (tokens.peek().type === 'punctuation' && tokens.peek().value === '(') {
      tokens.next()

      while (!(tokens.peek().type === 'punctuation' && tokens.peek().value === ')')) {
        if (tokens.peek().type !== 'identifier') {
          tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
        }

        node.params.push({
          type: 'Identifier',
          name: tokens.peek().value
        })

        tokens.next()

        if (tokens.peek().type === 'punctuation' && tokens.peek().value === ',') {
          tokens.next()
        }
      }

      tokens.next()

      if (tokens.peek().type === 'operator' && tokens.peek().value === '->') {
        tokens.next()

        if (tokens.peek().type === 'punctuation' && tokens.peek().value === '{') {
          tokens.next()

          node.body.type = 'FunctionBody'

          let count = 0
          while (!(tokens.peek().type === 'punctuation' && tokens.peek().value === '}') || count > 0) {
            if (tokens.peek().type === 'punctuation' && tokens.peek().value === '{') {
              count++
            } else if (tokens.peek().type === 'punctuation' && tokens.peek().value === '}') {
              count--
            }
            node.body.body.push(tokens.next())
          }

          tokens.next()
        } else if (tokens.peek().type === 'identifier') {
          node.body.type = 'FunctionBody'
          node.body.body.push({ type: 'keyword', value: 'return' })

          node.body.body.push({ type: 'identifier', value: tokens.peek().value })
          tokens.next()

          if (tokens.peek().type === 'punctuation' && tokens.peek().value === '(') {
            node.body.body.push(tokens.next())
            let count = 0
            while (!(tokens.peek().type === 'punctuation' && tokens.peek().value === ')') || count > 0) {
              if (tokens.peek().type === 'punctuation' && tokens.peek().value === '(') {
                count++
              } else if (tokens.peek().type === 'punctuation' && tokens.peek().value === ')') {
                count--
              }
              node.body.body.push(tokens.next())
            }
            node.body.body.push(tokens.next())
          }
        } else if (tokens.peek().type === 'keyword' && tokens.peek().value === 'none') {
          node.body.type = 'FunctionBody'
          node.body.body.push({ type: 'keyword', value: 'return' })
          node.body.body.push(tokens.next())
        } else if (tokens.peek().type === 'number' || tokens.peek().type === 'literal') {
          node.body.type = 'FunctionBody'
          node.body.body.push({ type: 'keyword', value: 'return' })
          node.body.body.push(tokens.next())
        } else {
          tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
        }
      } else {
        tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
      }
    } else {
      tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
    }
  } else {
    tokens.croak(`Can't handle token: ${ tokens.peek().value }`)
  }

  return node
}

export default {
  is,
  parse
}